Code
# Import required libraries
import os
import numpy as np
import pandas as pd
import xarray as xr
import rioxarray as rxr
import geopandas as gpd
import matplotlib.pyplot as plt
#from IPython.display import Markdown
#MarkdownNovember 29, 2025
Link to GitHub repository: Mapping environmental and social impacts of Eaton and Palisades fires
The Eaton and Palisades fires, which ignited almost simultaneously in early January 2025, showed not only the ecological vulnerability of Los Angeles County’s foothill and coastal wild-land urban interface zones but also the deep social dimensions embedded within wildfire disasters. Using remote sensing tools such as Landsat based false color imagery, environmental monitoring efforts can clearly delineate burn severity, vegetation loss and fire scar patterns that acts as critical information for assessing ecological recovery and guiding restoration. Yet the impacts of these fires extended far beyond the physical landscape. Thousands of homes were destroyed, tens of thousands of residents were displaced, and long standing inequities shaped who suffered most, who could rebuild and how quickly communities could recover. Factors such as income level, housing security, access to insurance, language barriers, transportation availability, and trust in public institutions strongly influenced how individuals responded to evacuation orders, accessed emergency services, and navigated post-fire assistance. By integrating advanced data visualization with an understanding of these social realities, environmental monitoring becomes not only a scientific exercise but also a tool for informing more just, community-centered wildfire resilience planning
This analysis combines the environmental monitoring with social vulnerability data to show how the Eaton and Palisades fires affected both the natural landscape and the communities living within it.
The analysis illustrates Python-based approaches for geospatial investigation: - Use xarray and rioxarray to create false-color images from Landsat 8 SWIR, NIR, and Red bands, revealing burn scars. - Combine raster satellite data with vector layers (fire perimeters and census tracts) in geopandas to integrate multiple data sources. - Maintain spatial accuracy by managing coordinate reference systems with rio.write_crs() and to_crs(). - Perform environmental justice analysis by using spatial joins and clipping to examine socioeconomic vulnerability in the burn-affected areas.
This dataset is a simplified collection of bands (red, green, blue, near-infrared and shortwave infrared) from the Landsat Collection 2 Level-2 atmosperically corrected surface reflectance data, collected by the Landsat 8 satellite. The data was retrieved from the Microsoft Planetary Computer data catalogue and clipped to an area surrounding the fire perimeters.
This dataset is dissolved fire perimeters/boundaries for Eaton and Palisades fires. The data can be accessed from the County of Los Angeles Open Data.
The 2024 California Environmental Justice Index (EJI), developed by the CDC and ATSDR, offers census tract-level information on both environmental and socioeconomic factors. This analysis utilizes the dataset to examine demographic characteristics, poverty levels, and environmental burden indicators across communities in California.
Fire perimeter data define the spatial extent of the fires, enabling focused analysis on the most impacted areas. Each dataset includes polygon geometries representing the fire boundaries, along with corresponding area and perimeter measurements.
| Dataset | Features | Columns | Geometry Type |
|:---------------|-----------:|----------:|:----------------|
| Eaton Fire | 20 | 5 | Polygon |
| Palisades Fire | 21 | 5 | Polygon |
The eaton and palisades datasets both have 5 columns (OBJECTID, type, Shape_Are, Shape_Len and geometry) with the same data types. The data types used are appropriate for all values in their respective columns. There is no missing data in the column. There are 20 rows in eaton dataset and 21 rows in palisades dataset.
Both of the dataset has same CRS (EPSG:3857), which is projected coordinate system that uses the Mercator projection to display the spherical Earth on a flat map.
<xarray.Dataset> Size: 78MB
Dimensions: (y: 1418, x: 2742)
Coordinates:
* y (y) float64 11kB 3.799e+06 3.799e+06 ... 3.757e+06 3.757e+06
* x (x) float64 22kB 3.344e+05 3.344e+05 ... 4.166e+05 4.166e+05
time datetime64[ns] 8B ...
Data variables:
red (y, x) float32 16MB ...
green (y, x) float32 16MB ...
blue (y, x) float32 16MB ...
nir08 (y, x) float32 16MB ...
swir22 (y, x) float32 16MB ...
spatial_ref int64 8B ...array([3799050., 3799020., 3798990., ..., 3756600., 3756570., 3756540.])
array([334410., 334440., 334470., ..., 416580., 416610., 416640.])
[1 values with dtype=datetime64[ns]]
[3888156 values with dtype=float32]
[3888156 values with dtype=float32]
[3888156 values with dtype=float32]
[3888156 values with dtype=float32]
[3888156 values with dtype=float32]
[1 values with dtype=int64]
PandasIndex(Index([3799050.0, 3799020.0, 3798990.0, 3798960.0, 3798930.0, 3798900.0,
3798870.0, 3798840.0, 3798810.0, 3798780.0,
...
3756810.0, 3756780.0, 3756750.0, 3756720.0, 3756690.0, 3756660.0,
3756630.0, 3756600.0, 3756570.0, 3756540.0],
dtype='float64', name='y', length=1418))PandasIndex(Index([334410.0, 334440.0, 334470.0, 334500.0, 334530.0, 334560.0, 334590.0,
334620.0, 334650.0, 334680.0,
...
416370.0, 416400.0, 416430.0, 416460.0, 416490.0, 416520.0, 416550.0,
416580.0, 416610.0, 416640.0],
dtype='float64', name='x', length=2742))Summary of the NetCDF dataset This dataset is a remote sensing raster dataset loaded as xarray.Dataset. The total size of the dataset is 78MB. The dataset exploration gave an information on dimensions, coordinates nad data variables.
There are two spatial dimensions on dataset. The (y: 1418) represents the vertical spatial dimension (rows) and (x: 2742) represents the horizontal spatial dimension (columns).
The dataset has coordinate arrays for both x and y, stored as float64 values that corresponds to their respective spatial map coordinates. There is a only one time coordinate stored as datetime64[ns], that indicates when the image was taken.
There are five different spectral bands: red, green, blue, nir08 and swir22, and they have the same pixel grid (float32). A spatial_ref variable is also included to store the map projection information.
Check the coordinate reference system of the landsat data and transform as necessary.
rio.crs to print what is the CRS of this dataset. Is this a geospatial object?spatial_ref.crs_wkt attribute of the dataset.PROJCS["WGS 84 / UTM zone 11N",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-117],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","32611"]]
rio.write_crs() and the spatial reference information from part b.<xarray.Dataset> Size: 78MB
Dimensions: (y: 1418, x: 2742)
Coordinates:
* y (y) float64 11kB 3.799e+06 3.799e+06 ... 3.757e+06 3.757e+06
* x (x) float64 22kB 3.344e+05 3.344e+05 ... 4.166e+05 4.166e+05
time datetime64[ns] 8B ...
spatial_ref int64 8B 0
Data variables:
red (y, x) float32 16MB ...
green (y, x) float32 16MB ...
blue (y, x) float32 16MB ...
nir08 (y, x) float32 16MB ...
swir22 (y, x) float32 16MB ...
To create a True color image, follow the following steps:
xarray.Dataset holding the Landsat data,numpy.array using the to_array() method, and then.plot.imshow() to create an RGB image with the data. There will be two warnings, that’s ok./opt/anaconda3/envs/eds220-env/lib/python3.11/site-packages/matplotlib/cm.py:478: RuntimeWarning: invalid value encountered in cast
xx = (xx * 255).astype(np.uint8)
nan values. HINT: There are many ways of doing so. One option is to use numpy.isnan().# Identify 'nan' values in bands
for i in ['red', 'green', 'blue']:
# .isnull() creates a boolean array (True where NaN)
# .sum() sums the True values (counts the NaNs)
# .item() converts the single result to a standard Python integer
nan_count = landsat[i].isnull().sum().item()
print(f"The {i} band has {nan_count} Nan values.")The red band has 0 Nan values.
The green band has 1 Nan values.
The blue band has 109 Nan values.
.fillna() mehtod for xarray.Datasets to substitute the any nan values in the Landsat data for zero.The first true color image (part a) was plotted directly from the red, green and blue bands without modifying the dataset. The image worked, but we got warnings because some of the data had Nan (missing) values. These missing values caused problems during plotting. Additionally, due to the presence of very bright cloud pixels, many of the other colors appeared darker or washed out, even when using the robust=True to ignore extreme outliers.
In part (part e), we replaced all Nan values with zeros before plotting again. This removed the missing values issue allowing the plot to scale the data more smoothly. So, the second true color image displayed without warnings. The second true color image looks cleaner and has better contrast. It doesn’t have the plotting problems seen in the first image.
Without creating any new variables, create a false color image by plotting the short-wave infrared (swir22), near-infrared, and red variables (in that order).
# Initialize the map
fig, ax = plt.subplots(figsize = (10, 8))
# Plot the false color map
landsat[['swir22', 'nir08', 'red']].to_array().plot.imshow(robust = True,
ax = ax,
add_colorbar = False)
# Plot fires perimeter on false color map
fires.boundary.plot(ax = ax, color = 'red', linewidth = 2)
# Add text for first fire (adjust index and name as needed)
ax.text(fires.geometry.centroid.x.values[0] - 11000, fires.geometry.centroid.y.values[0] + 8000, 'Eaton Fire',
fontsize = 14, weight = 'bold', color = 'white', ha = 'center', va = 'center')
# Add text for second fire (adjust index and name as needed)
ax.text(fires.geometry.centroid.x.values[-1] - 9000, fires.geometry.centroid.y.values[-1] + 5000, 'Palisades Fire',
fontsize = 14, weight = 'bold', color = 'white', ha = 'center', va= 'center')
# Add title to the map
plt.title('False color image for Eaton and Palisades fire', fontsize = 12, weight = 'bold')
# Remove axes ticks
ax.set_xticks([])
ax.set_yticks([])
# Remove axes labels
ax.set_xlabel("")
ax.set_ylabel("")
# Add a scalebar
#ax.add_artist(ScaleBar(1, box_color="white",location="lower left"))
plt.show()This map shows a false color image made from Landsat data for Eaton and Palisades fire of the Los Angeles County. The map uses three bands: SWIR2, NIR and Red, assigned to the red, green and blue color channels. In this image, vegetation looks green because they reflect a lot of near-infrared light. The fire burned areas and bare ground looks brown. The urban areas usually appear purple or gray. The water looks black. The boundaries of the Eaton Fire and Palisades fire are delineated with red outlines. Each fire is labeled.
This combination of bands is useful for spotting burn scars and understanding fire damage because SWIR2 reacts strongly to moisture changes, and NIR highlights how healthy the vegetation is. Together, these bands make it easy to see where fires have changed the landscape.
Landsat Collection 2 Level-2. Microsoft Planetary Computer. Retrieved 15 Nov, 2025. https://planetarycomputer.microsoft.com/dataset/landsat-c2-l2.
Palisades and Eaton Dissolved Fire Perimeters. (2025) County of Los Angeles Open Data. https://data.lacounty.gov/maps/ad51845ea5fb4eb483bc2a7c38b2370c/about.
Why Is That Forest Red and That Cloud Blue?. (2014, March 4). NASA Earth Observatory. https://earthobservatory.nasa.gov/features/FalseColor.
What Are the Band Designations for the Landsat Satellites?.(2025, July 11). U.S. Geological Survey. https://www.usgs.gov/faqs/what-are-band-designations-landsat-satellites.
Common Landsat Band Combinations. (2021, November 12). U.S. Geological Survey. https://www.usgs.gov/media/images/common-landsat-band-combinations
@online{poudel2025,
author = {Poudel, Aakriti},
title = {Mapping 2025 {Eaton} and {Palisades} Fires: {Environmental}
and Social Impacts},
date = {2025-11-29},
url = {https://aakriti-poudel-chhetri.github.io/posts/2025-12-eaton-palisades-fires-eji/},
langid = {en}
}